#include "GlyphParser.h"

#include "SimpleParser.h"
#include "DoubleParser.h"
#include "QStringParser.h"

#include <QXmlStreamReader>
#include <QString>

namespace Ipc2581b
{

GlyphParser::GlyphParser(
    QStringParser *&_charCodeParser
    , DoubleParser *&_lowerLeftXParser
    , DoubleParser *&_lowerLeftYParser
    , DoubleParser *&_upperRightXParser
    , DoubleParser *&_upperRightYParser
    , SimpleParser *&_simpleParser
):    m_charCodeParser(_charCodeParser)
    , m_lowerLeftXParser(_lowerLeftXParser)
    , m_lowerLeftYParser(_lowerLeftYParser)
    , m_upperRightXParser(_upperRightXParser)
    , m_upperRightYParser(_upperRightYParser)
    , m_simpleParser(_simpleParser)
{

}

bool GlyphParser::parse(QXmlStreamReader *reader)
{
    /* Pre */

    m_result.reset(new Glyph());

    /* Attributes */

    QStringRef data;
    if (reader->attributes().hasAttribute(QStringLiteral("charCode")))
    {
        data = reader->attributes().value(QStringLiteral("charCode"));
        if (!m_charCodeParser->parse(reader, data))
            return false;
        m_result->charCode = m_charCodeParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("charCode: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("lowerLeftX")))
    {
        data = reader->attributes().value(QStringLiteral("lowerLeftX"));
        if (!m_lowerLeftXParser->parse(reader, data))
            return false;
        m_result->lowerLeftX = m_lowerLeftXParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("lowerLeftX: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("lowerLeftY")))
    {
        data = reader->attributes().value(QStringLiteral("lowerLeftY"));
        if (!m_lowerLeftYParser->parse(reader, data))
            return false;
        m_result->lowerLeftY = m_lowerLeftYParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("lowerLeftY: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("upperRightX")))
    {
        data = reader->attributes().value(QStringLiteral("upperRightX"));
        if (!m_upperRightXParser->parse(reader, data))
            return false;
        m_result->upperRightX = m_upperRightXParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("upperRightX: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("upperRightY")))
    {
        data = reader->attributes().value(QStringLiteral("upperRightY"));
        if (!m_upperRightYParser->parse(reader, data))
            return false;
        m_result->upperRightY = m_upperRightYParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("upperRightY: Attribute is required"));
        return false;
    }

    /* Elements */

    while (reader->readNextStartElement())
    {
        auto name = reader->name();
        if (m_simpleParser->isSubstitution(name))
        {
            if (!m_simpleParser->parse(reader))
                return false;
            auto result = m_simpleParser->result();
            m_result->simpleList.append(result);
        }
        else
            reader->skipCurrentElement();
    }

    /* Post */

    // TODO: Check multiplicity of elements/attributes

    return true;
}

Glyph *GlyphParser::result()
{
    return m_result.take();
}

}